/*
 * Copyright (c) 2003 TWINDIVIDIVISION SMPPEventHandler.java
 */
package guru.mercurio.eps.sSMPP;

import guru.mercurio.common.PhoneAddress;
import guru.merlin.core.ConfigurationCantHandException;
import guru.merlin.core.CantHandException;
//import guru.merlin.core.CantHandException_;
//import guru.merlin.core.EPExecutionException;
//import guru.merlin.core.EPInfrastructureException;
import guru.mercurio.eps.sSMPP.DataHandler;
import guru.merlin.core.PeerCantHandException;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Properties;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.smpp.Data;
import org.smpp.ServerPDUEvent;
import org.smpp.Session;
import org.smpp.TCPIPConnection;
import org.smpp.TimeoutException;
import org.smpp.pdu.Address;
import org.smpp.pdu.AddressRange;
import org.smpp.pdu.BindReceiver;
import org.smpp.pdu.BindRequest;
import org.smpp.pdu.BindResponse;
import org.smpp.pdu.BindTransciever;
import org.smpp.pdu.BindTransmitter;
import org.smpp.pdu.CancelSM;
import org.smpp.pdu.CancelSMResp;
import org.smpp.pdu.DataSM;
import org.smpp.pdu.EnquireLink;
import org.smpp.pdu.EnquireLinkResp;
import org.smpp.pdu.PDU;
import org.smpp.pdu.QuerySM;
import org.smpp.pdu.QuerySMResp;
import org.smpp.pdu.Request;
import org.smpp.pdu.Response;
import org.smpp.pdu.SubmitMultiSM;
import org.smpp.pdu.SubmitMultiSMResp;
import org.smpp.pdu.SubmitSM;
import org.smpp.pdu.SubmitSMResp;
import org.smpp.pdu.UnbindResp;

/**
 * @author Santiago Ventura Infante Clase <code>SMPPOperator</code> Provee la implementacin de los mtodos definidos en la <br>
 *         interfaz SMPPConnector. <br>
 *         Bsicamente la implementacin de los mtodos envuelven las operaciones ms comunes especificadas <br>
 *         en el protocolo SMPP: <br>
 *         BIND <br>
 *         UNBIND <br>
 *         SUMIT_SM <br>
 *         SUBMIT_MULTI_SM <br>
 *         <br>
 *         Los mtodos implementados tambin incluyen aquellos esenciales para el establecimientos de la <br>
 *         comunicacin entre un ESME y SMSC, tales como la conexin TCP/IP y una sesin.. <br>
 *         Esta clase se vale de un archivo de propiedades para su funcionamiento, de lo contrario su <br>
 *         uso es imposible. El archivo de propiedades debe contener las claves y valores de <br>
 *         los parmetros <br>
 *         necesarios para cada una de las operaciones definidas por el protocolo SMPP. <br>
 * @version 0.1
 */
public class SMPPOperator implements SMPPConnector, Runnable {
    static Logger logger = Logger.getLogger(SMPPOperator.class);
    
    // ATRIBUTOS PARA LA CARGA DEL ARCHIVO DE PROPIEDADES
    private String smscId = null; // Identifica al operador ej. digitel,
    
    // telcel, movilnet, etc
    
    private String propertiesPath = null; // Indica la ruta donde se encuentra
    
    // el archivo de propiedades. Ej.
    // X:\\guru\\conf\\
    
    private String propertiesFile = null; // Nombre del archivo de
    
    //Objeto properties con las propiedades del protocolo smpp
    Properties properties = null;
    
    /* ATRIBUTOS PARA LAS OPERACIONES DEL SMPPOperator */
    SMPPEventHandler pduListener = null; /*
     * Instancia de la clase SMPPEventHandler que recibe todos los PDUs recibidos desde el SMSC.
     */
    
    protected String nodeID; // ID del NODO
    
    private String ipAddress; // CONNECTION La direccin IP del SMSC
    
    private int port; // CONNECTION El nmero de puerto remoto del SMSC
    
    private TCPIPConnection connection = null; // CONNECTION Objeto connection,
    
    // que representa la conexin
    // con el SMSC
    
    private Session session = null; // CONNECTION Representa la comunicacin con
    
    // el SMSC
    
    private boolean autoReconnect = false; // CONNECTION Define la reconexin
    
    // automtica true/false
    
    private boolean connected = false; // CONNECTION Representa el status de la
    
    // conexin true (conectado) / false
    // (desconectado)
    
    private boolean bound = false; // BIND Representa el status del enlace true
    
    // (enlazado) / false (desenlazado)
    
    private BindRequest bindRequest = null; // BIND Representa la peticin de
    
    // enlace al SMSC
    
    private BindResponse bindResponse = null; // BIND Representa la respuesta
    
    // del SMSC a la peticin de
    // enlace
    
    private boolean asynchronous = false; // BIND Estaclece el status de la
    
    // comunicacin true (asynchronous)
    // / false (synchronous)
    
    private String systemId; // BIND Parmetro que identifica al ESME ante el
    
    // SMSC
    
    private String password; // BIND Parmetro usado por el SMSC para
    
    // autenticar al ESME
    
    private String systemType; // BIND Parmetro usado para categorizar al tipo
    
    // de ESME que esta enlazndose con el SMSC
    
    private byte interfaceVersion; // BIND Parmetro usado para indicar la
    
    // versin del protocolo SMPP
    
    private byte addrTon; // BIND Este campo define el tipo de nmero (Type of
    
    // Number) a ser usado en los parmetros de
    // direcciones SME.
    
    private byte addrNpi; // BIND Este campo define el Indicador de Plan
    
    // Numrico (Numeric Plan Indicator) a ser usado en
    // los parmetros de direcciones SME.
    
    private String addrRange; // BIND Cadema que representa al parmetro smpp,
    
    // address_range.
    
    private String bindType = "tr"; // BIND tipo de enlace (r/R: receiver, t/T:
    
    // transmitter, tr/TR: transceiver)
    
    private AddressRange addressRange = null; // BIND El objeto addressRange
    
    // es usado por los comandos
    // Bind Receiver y el Bind
    // Transceiver.
    
    private SubmitSM submitSMRequest = null; // SUBMIT Representa la peticin
    
    // de para el envo de un
    // mensaje corto desde el ESME
    // al SMSC
    
    private SubmitSMResp submitSMResponse = null; // SUBMIT Representa la
    
    // respuesta por parte del
    // SMSC a la peticin del
    // ESME para el envo de un
    // mensaje corto
    
    // private Address sourceAddress = null; //SUBMIT Representa la direccin
    // del ESME, desde donde se origino el mensaje
    // private Address destAddress = null; //SUBMIT Representa la direccin del
    // SME destino. Para una estacin mvil este es el nmero de directorio.
    private String serviceType; // SUBMIT Este parmetro sirve para indicar el
    
    // servicio asociado con el mensaje. WAP, VOICE
    // MAIL NOTIFICATION, etc.
    
    private byte sourceAddrTon; // SUBMIT Este campo define el tipo de nmero
    
    // (Type of Number) a ser usado en los
    // parmetros de direcciones SME.
    
    private byte sourceAddrNpi; // SUBMIT Este campo define el Indicador de Plan
    
    // Numrico (Numeric Plan Indicator) a ser usado
    // en los parmetros de direcciones SME.
    
    // private String srcAddr; //SUBMIT Esta cadena representa la direccin del
    // ESME desde donde se origino el mensaje
    private byte destAddrTon; // SUBMIT Este campo define el tipo de nmero
    
    // (Type of Number) a ser usado en los
    // parmetros de direcciones SME.
    
    private byte destAddrNpi; // SUBMIT Este campo define el Indicador de Plan
    
    // Numrico (Numeric Plan Indicator) a ser usado
    // en los parmetros de direcciones SME.
    
    private byte esmClass; // SUBMIT Este parmetro es usado para indicar un
    
    // mensaje especial asociado con el SM.
    
    private byte protocolId; // SUBMIT Identifica al protocolo. GSM. TDMA,
    
    // CDMA, etc.
    
    private byte priorityFlag; // SUBMIT Asigna el nivel de prioridad (0-3).
    
    // Siendo 3 la de mayor prioridad.
    
    private String scheduleDeliveryTime; // SUBMIT Este parmetro especifica
    
    // cuando el mensaje debe ser
    // entregado por el SMSC.
    
    private String validityPeriod; // SUBMIT Este parmetro le indica al SMSC
    
    // cuando el mensaje debe ser descartado, si
    // no es entregado a su destinatario.
    
    private byte registeredDelivery; // SUBMIT Este parmetro es usado para
    
    // pedirle al SMSC un recibo de entrega
    // del mensaje
    
    private byte replaceIfPresentFlag; // SUBMIT Este parmetro es usado para
    
    // pedirle al SMSC que reemplace un
    // mensaje enviado previamente.
    
    private byte dataCoding; // SUBMIT Indica al SMSC como los datos deben
    
    // ser codificados.
    
    private byte smDefaultMsgId; // SUBMIT Indica al SMSC el indice para un
    
    // mensaje predefinido.
    
    private short smLength; // SUBMIT Este parmetro es usado para indicar la
    
    // longitud de el short_message.
    
    private String shortMessage; // SUBMIT Representa al mensaje corto.
    
    private String messageId; // SUBMIT Representa el identificador nico del
    
    // mensaje, asignado por el SMSC a cada mensaje
    // corto enviado.
    
    private int intTimeout = 30; // RECEIVE Tiempo de espera (segundos) por
    
    // la recepcin de mensajes. Debe ser
    // convertido a milisegundos.
    
    private SubmitMultiSM subMultiRequest = null;
    
    // SUBMIT MULTI Representa la peticin de para el envo de un mensaje corto
    // desde el ESME al SMSC.Este mensaje ser entregado a multiples
    // destinatarios.
    private SubmitMultiSMResp subMultiResponse = null;
    
    // SUBMIT MULTI Representa la respuesta por parte del SMSC a la peticin del
    // ESME para el envo de un mensaje corto. Este mensaje ser entregado a
    // multiples destinatarios.
    private Vector destAddresses = null; // Contiene las direcciones de
    
    // destino donde el SMSC debe
    // entregar el mensaje. Es usada
    // cuando el mensaje debe ser
    // entregado a multiples
    // destinatarios.
    
    private DataSM dataSMrequest = null; // DATA SM
    
    // LOS SIGUIENTES ATRIBUTOS DE TIPO CADENA CONTENIEN EL RESULTADO DE
    // LA EJECUCION DE LOS METODOS IMPLEMENTADOS DE LA INTERFAZ SMPPConnector
    
    private String openConnectionResult; // Contiene el resultado de la
    
    // operacin openConnection()
    
    private String closeConnectionResult; // Contiene el resultado de la
    
    // operacin closeConnection()
    
    private String getBindResult; // Contiene el resultado de la operacin
    
    // getBind()
    
    private String closeBindResult; // Contiene el resultado de la operacin
    
    // closeBind()
    
    private String stopReceiveSMSResult; // Contiene el resultado de la
    
    private long enquireLinkTime;
    
    // operacin stopReceiveSMS()
    
    private Thread toReceiver;
    
    private guru.mercurio.eps.sSMPP.DataHandler dataHandler;
    
    private ReceivedMessageHandler messageHandler;
    
    private boolean keepReceiving = true;
    
    /**
     * Constructor sin argumentos. Los atributos smscId, propertiesPath y propertiesFile deben ser asignados al objetos SMPPOperator, para poder cargar el archivo de propiedades.
     */
    public SMPPOperator() {
        this.setToReceiver(new Thread(this));
        // receivedMessageStore = new ReceivedMessageStore();
    }
    
    /**
     * Constructor con argumentos
     *
     * @param smsc
     *            Identifica al operador (SMSC) ej. digitel, telcel, movilnet, etc
     * @param pPath
     *            La ruta donde se encuentra el archivo de propiedades
     * @param pFile
     *            El nombre del archivo de propiedades
     * @param DataHandler
     *            handler
     */
    public SMPPOperator(String smsc, String pPath, String pFile, DataHandler handler) throws IOException {
        setSmscId(smsc);
        setPropertiesPath(pPath);
        setPropertiesFile(pFile);
        loadProperties();
        this.setToReceiver(new Thread(this));
        dataHandler = handler;
    }
    
    // IMPLEMENTACION DE LOS METODOS DE LA INTERFAZ SMPPConnector
    
    /**
     * Establece la conexin va TCP/IP con el SMSC
     *
     * @param smscIpAddress
     *            Direccin IP del SMSC
     * @param smscPort
     *            Puerto de conexin del SMSC
     * @return 1 si se ha establecido la conexin, 2 si la conexin ya existe, y 0 cualquier otra cosa
     */
    public int openConnection(String smscIpAddress, int smscPort) throws CantHandException {//MOD SANTIAGO
        int successfull = 0;
        String msg;
        if (connection == null || this.isConnected() == false) {
            try {
                Socket socket = new Socket(InetAddress.getByName(smscIpAddress), smscPort);
                connection = new TCPIPConnection(socket);
                connection.setCommsTimeout(0);
                connection.setReceiveTimeout(500);
                session = new Session(connection);                
                messageHandler = new ReceivedMessageHandler(this.dataHandler, this.session, this.properties);
                successfull = 1;
                if (session!=null) {
                    this.setConnected(true);
                    msg = "Connection TCP/IP has been established successfully. " + smscIpAddress + " " + smscPort; //MOD SANTIAGO
                    logger.info(msg);                    
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new PeerCantHandException(e.toString());
            }
        } else if (this.isConnected()) {
            successfull = 2;
            if (logger.isDebugEnabled()) {
                logger.debug("Connection TCP/IP already had been established previously.");
            }
        }
        return successfull;
    }
    
    /**
     * Establece la conexin va TCP/IP con el SMSC
     *
     * @return 1 si se ha establecido la conexin, 2 si la conexin ya existe, y 0 cualquier otra cosa
     */
    public int openConnection() throws CantHandException {
        int successfull = 0;
        try {
            successfull = openConnection(this.ipAddress, this.port);
            messageHandler = new ReceivedMessageHandler(this.dataHandler, this.session, this.properties);
        } catch (Exception e) {
            throw new PeerCantHandException(e.getMessage());
        }
        return successfull;
    }
    
    /**
     * Cierra la conexin con el SMSC
     */
    public void closeConnection() {//MOD SANTIAGO
        String msg = "";
        if (connection != null) {
            try {
                session.close();
                this.setConnected(false);
                msg = "Connection TCP/IP has been closed successfully.";
                logger.info(msg);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //connection = null;
            }
        } else {
            msg = "Connection TCP/IP already has been closed previously.";
            logger.info(msg);
        }
    }
    
    /**
     * Establece el enlace con el SMSC
     *
     * @return 1 si se ha establecido el enlace con el SMSC, 2 si el enlace ya existe, y 0 cualquier otra cosa
     */
    public int getBind() throws CantHandException {
        int successfull = 0;
        if (session.isBound()) {
            successfull = 2;
            return successfull;
        }
        
        if (session != null) {
            String bindT = this.getBindType();
            try {
                // Se establece el enlace, segn el valor que tenga el parmetro
                // bindType
                if (bindT.equalsIgnoreCase("t")) {
                    bindRequest = new BindTransmitter();
                } else if (bindT.equalsIgnoreCase("r")) {
                    bindRequest = new BindReceiver();
                } else if (bindT.equalsIgnoreCase("tr")) {
                    bindRequest = new BindTransciever();
                } else {
                    logger.error("The type of bind to the smsc is not an option legal.");
                    return successfull;
                }
                
                // Se asigna los parmetros obligatorios para el enlace.
                bindRequest.setSystemId(this.systemId);
                bindRequest.setPassword(this.password);
                bindRequest.setSystemType(this.systemType);
                bindRequest.setInterfaceVersion(interfaceVersion);
                addressRange = new AddressRange(addrTon, addrNpi, addrRange);
                bindRequest.setAddressRange(addressRange);
                
                // Se efectua el enlace
                
                if (asynchronous) {
                    pduListener = new SMPPEventHandler(session);
                    bindResponse = session.bind(bindRequest, pduListener);
                } else {
                    bindResponse = session.bind(bindRequest);
                }
                // Si el enlace es exitoso hacemos true a la propiedad bound
                if (session.isBound()) {
                    this.setBound(true);
                    successfull = 1;
                }
            } catch (org.smpp.pdu.WrongLengthOfStringException wlose) {
                wlose.printStackTrace();
                throw new ConfigurationCantHandException(wlose.toString());
            } catch (org.smpp.pdu.ValueNotSetException vnse) {
                vnse.printStackTrace();
                throw new ConfigurationCantHandException(vnse.toString());
            } catch (Exception e) {
                throw new PeerCantHandException(e.toString());
            }
        }
        return successfull;
    }
    
    /**
     * Cierra el enlace, pero la conexin al SMSC permanece abierta. Esta operacin puede tomar algn tiempo si el enlace es asynchronous.
     */
    public void closeBind() { //MOD SANTIAGO
        UnbindResp unbindResponse = null;
        if (session != null) {
            try {
                if (session.isBound()) {
                    // Cerrar el enlace
                    unbindResponse = this.session.unbind();
                    messageHandler.processSMSCResponse(unbindResponse);
                    this.setBound(false);
                }
            } catch (org.smpp.pdu.ValueNotSetException vnse) {
                vnse.printStackTrace();
            } catch (org.smpp.TimeoutException te) {
                te.printStackTrace();
            } catch (org.smpp.pdu.PDUException pdue) {
                pdue.printStackTrace();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //session = null;
            }
        }
    }
    
    private boolean isANumber(String number) {
        try {
            new Long(number);
            return (true);
        } catch (Exception e) {
            return (false);
        }
    }
    
    private String getDestPhoneAddress(PhoneAddress destPhone) throws ConfigurationCantHandException {
        String str = "";
        
        switch (destAddrTon) {
            case 1:
                switch (destAddrNpi) {
                    case 1://DIGITEL
                        if ((destPhone.getLocal()).length() < 7) {
                            while ((destPhone.getLocal()).length() < 7) {
                                destPhone.setLocal("0" + destPhone.getLocal());
                            }
                        }
                        str = destPhone.getCountryCode() + destPhone.getAreaCode() + destPhone.getLocal();
                        break;
                    case 9:
                        String narear = destPhone.getAreaCode();
                        if (destPhone.getCountryCode().equals("58")) {
                            if ((destPhone.getLocal()).length() < 7) {
                                while ((destPhone.getLocal()).length() < 7) {
                                    destPhone.setLocal("0" + destPhone.getLocal());
                                }
                            }
                            if (narear.equals("412")) {//Digitel (03458412xxxxxxx)
                                str = "03458412" + destPhone.getLocal();
                            } else if (narear.equals("414")) {//Movistar
                                // (0270414xxxxxxx)
                                str = "0270414" + destPhone.getLocal();
                            } else if (narear.equals("416")) {//Movilnet (004xxxxxxx)
                                str = "004" + destPhone.getLocal();
                            } else if (narear.equals("418")) {//Infonet
                                // (04958418xxxxxxx)
                                str = "04958418" + destPhone.getLocal();
                            }
                        }
                        
                        if (destPhone.getCountryCode().equals("507")) {
                            int startlocal = Integer.parseInt(destPhone.getLocal().substring(0, 3));
                            if (startlocal >= 656 && startlocal <= 664) {//CDMA/TDMA (078)
                                str = "078" + destPhone.getCountryCode() + destPhone.getLocal();
                            } else if ((startlocal == 648)|| (startlocal == 647)  || (startlocal == 649)) {//GSM (152)
                                int startlocal2 = Integer.parseInt(destPhone.getLocal().substring(0, 4));
                                if ((startlocal2 >= 6480 && startlocal2 <= 6489) || startlocal2 == 6471 || startlocal2 <= 6491) {//GSM (152)
                                    str = "152" + destPhone.getCountryCode() + destPhone.getLocal();
                                }
                            } else if ((startlocal >= 650 && startlocal <= 653) || (startlocal >= 665 && startlocal <= 6672)) {//Cable&Wireless(117)
                                str = "117" + destPhone.getCountryCode() + destPhone.getLocal();
                            }
                        }
                        logger.info("WAU Address: " + str);
                        break;
                    default:
                        throw new ConfigurationCantHandException("Dont know destAddrNpi");
                }
                break;
            case 2:
                if ((destPhone.getLocal()).length() < 7) {
                    while ((destPhone.getLocal()).length() < 7) {
                        destPhone.setLocal("0" + destPhone.getLocal());
                    }
                }
                if (destPhone.getAreaCode().equals("416")) {
                    str = "158" + destPhone.getLocal();
                } else {
                    str = "0" + destPhone.getAreaCode() + destPhone.getLocal();
                }
                break;
            default:
                throw new ConfigurationCantHandException("Dont know destAddrNpi");
        }
        
        return str;
    }
    
    /**
     * Envia un mensaje al SMSC. El tipo de enlace debe ser como transmitter/transceiver
     *
     * @param destAddr
     *            Numero del destinatario del mensaje
     * @param shortMessage
     *            Mensaje corto que ser enviado al destinatario.
     * @return true si se ha enviado el mensaje al SMSC, false cualquier otra cosa
     */
    public void submitSMS(PhoneAddress destPhone, String shortMessage, String shortCode, int sequence) throws CantHandException {
        String msg = "";
        //poner el 139
        submitSMRequest = new SubmitSM();
        if (destPhone.getAreaCode().equals("416") && destAddrTon != 1) {
            shortCode = "139" + shortCode;
        }

        msg = "submitSMS request received for destPhone='" + destPhone + "', msg='" + shortMessage + "', shortCode='" + shortCode.trim() + "'";
        logger.info(msg);
        
        try {
            String str = getDestPhoneAddress(destPhone);
            /*
             * switch (destAddrTon) { case 1: switch (destAddrNpi) { case 1://DIGITEL if ((destPhone.getLocal ()).length () < 7) { while ((destPhone.getLocal ()).length () < 7) { destPhone.setLocal ("0" + destPhone.getLocal ()); } } //str = "0" + destPhone.getAreaCode() + destPhone.getLocal(); str = destPhone.getCountryCode () + destPhone.getAreaCode () + destPhone.getLocal (); break; case 9: if ((destPhone.getLocal ()).length () < 7) { while ((destPhone.getLocal ()).length () < 7) { destPhone.setLocal ("0" + destPhone.getLocal ()); } }
             *
             * String narear = destPhone.getAreaCode (); if (narear.equals ("412")) {//Digitel (03458412xxxxxxx) str = "03458412" + destPhone.getLocal (); } else if (narear.equals ("414")) {//Movistar (0270414xxxxxxx) str = "0270414" + destPhone.getLocal (); } else if (narear.equals ("416")) {//Movilnet (004xxxxxxx) str = "004" + destPhone.getLocal (); } else if (narear.equals ("418")) {//Infonet (04958418xxxxxxx) str = "04958418" + destPhone.getLocal (); } break; default: throw new ConfigurationCantHandException ("Dont know destAddrNpi"); } break; case 2: if ((destPhone.getLocal ()).length () < 7) {
             * while ((destPhone.getLocal ()).length () < 7) { destPhone.setLocal ("0" + destPhone.getLocal ()); } } if (destPhone.getAreaCode ().equals ("416")) { str = "158" + destPhone.getLocal (); } else { str = "0" + destPhone.getAreaCode () + destPhone.getLocal (); } break; default: throw new ConfigurationCantHandException ("Dont know destAddrNpi"); }
             */
            // Se asigna los parmetros obligatorios para el envo del mensaje.
            submitSMRequest.setServiceType(serviceType);
            
            Address destAddress = new Address(destAddrTon, destAddrNpi, str);
            //logger.info("Destination Address=" + destAddress.toString());
            submitSMRequest.setDestAddr(destAddress);
            
            Address sourceAddress;
            if (isANumber(shortCode)) {
                sourceAddress = new Address(sourceAddrTon, sourceAddrNpi, shortCode);
            } else {
                sourceAddress = new Address(Byte.parseByte("5"), sourceAddrNpi, shortCode);
            }
            logger.info("source address debug "+sourceAddress.debugString());
            submitSMRequest.setSourceAddr(sourceAddress);
            
            submitSMRequest.setEsmClass(esmClass);
            submitSMRequest.setProtocolId(protocolId);
            submitSMRequest.setPriorityFlag(priorityFlag);
            submitSMRequest.setScheduleDeliveryTime(scheduleDeliveryTime);
            submitSMRequest.setValidityPeriod(validityPeriod);
            
            submitSMRequest.setRegisteredDelivery(registeredDelivery);
            
            submitSMRequest.setReplaceIfPresentFlag(replaceIfPresentFlag);
            submitSMRequest.setDataCoding(dataCoding);
            submitSMRequest.setSmDefaultMsgId(smDefaultMsgId);
            // submitSMRequest.setSmLength(smLength);
            submitSMRequest.setShortMessage(shortMessage);
            submitSMRequest.setAlertOnMsgDelivery(false);
            
            // setMessageId("");
            
            if (session.isBound()) {
                // Se efectua el envo del mensaje
                // submitSMRequest.assignSequenceNumber(true);
                submitSMRequest.setSequenceNumber(sequence);
                
                session.submit(submitSMRequest); // ojo, esto devuelve la
                // respuesta su estamos en
                // sincrono.
                
                if (!asynchronous) {
                    // messageHandler.SMSCResponse(response); donde response es
                    // lo que retorna el submit anterior.
                    throw new PeerCantHandException("No se como manejar una comunicacin sncrona");
                }
            } else {
                throw new PeerCantHandException("SMPPEP is not bound with the smsc");
            }
        } catch (org.smpp.pdu.ValueNotSetException vnse) {
            throw new ConfigurationCantHandException(vnse.toString());
        } catch (org.smpp.pdu.WrongLengthOfStringException wlose) {
            throw new ConfigurationCantHandException(wlose.toString());
        } catch (org.smpp.pdu.WrongDateFormatException wdfe) {
            throw new ConfigurationCantHandException(wdfe.toString());
        } catch (org.smpp.TimeoutException te) {
            throw new PeerCantHandException(te.toString());
        } catch (org.smpp.pdu.PDUException pdue) {
            throw new PeerCantHandException(pdue.toString());
        } catch (IOException ioe) {
            throw new PeerCantHandException(ioe.toString());
        } catch (org.smpp.WrongSessionStateException wsse) {
            throw new PeerCantHandException(wsse.toString());
        } catch (NullPointerException e) {
            throw new PeerCantHandException(e.toString());
        }
    }
    
    /**
     * Envia multiples mensajes al SMSC. El tipo de enlace debe ser como transmitter/transceiver
     *
     * @param destAddresses
     *            Direcciones de los destinatarios del mensaje
     * @param shortMessage
     *            Mensaje corto que ser enviado a todos los destinatario.
     * @return true si se ha enviado el mensaje al SMSC, false cualquier otra cosa
     */
    /*
     * public boolean submitMultiSMS(Vector destAddresses, String shortMessage) { boolean successfull = false; subMultiRequest = new SubmitMultiSM(); Response response; try { // Se asigna los parmetros obligatorios para el envo del mensaje. subMultiRequest.setServiceType(serviceType); sourceAddress = new Address(sourceAddrTon, sourceAddrNpi, srcAddr); subMultiRequest.setSourceAddr(sourceAddress); // Asignamos las direcciones de destino del mensaje this.destAddresses = destAddresses; Iterator numOfDests = destAddresses.iterator(); int elements = 0; while (elements < destAddresses.size()) {
     * subMultiRequest.addDestAddress(new DestinationAddress(destAddrTon, destAddrNpi, (String) destAddresses.get(elements))); elements++; } subMultiRequest.setEsmClass(esmClass); subMultiRequest.setProtocolId(protocolId); subMultiRequest.setPriorityFlag(priorityFlag); subMultiRequest.setScheduleDeliveryTime(scheduleDeliveryTime); subMultiRequest.setValidityPeriod(validityPeriod); subMultiRequest.setRegisteredDelivery(registeredDelivery); subMultiRequest.setReplaceIfPresentFlag(replaceIfPresentFlag); subMultiRequest.setDataCoding(dataCoding); subMultiRequest.setSmDefaultMsgId(smDefaultMsgId);
     * //submitSMRequest.setSmLength(smLength); subMultiRequest.setShortMessage(shortMessage); setMessageId(""); if (session.isBound()) { // Se efectua el envo del mensaje if (asynchronous) { session.submitMulti(subMultiRequest); successfull = true; } else { response = session.submitMulti(subMultiRequest); messageHandler.SMSCResponse(response); successfull = true; } } } catch (org.smpp.pdu.ValueNotSetException vnse) { vnse.printStackTrace(); } catch (org.smpp.pdu.WrongLengthOfStringException wlose) { wlose.printStackTrace(); } catch (org.smpp.pdu.WrongDateFormatException wdfe) {
     * wdfe.printStackTrace(); } catch (org.smpp.TimeoutException te) { te.printStackTrace(); } catch (org.smpp.pdu.PDUException pdue) { pdue.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (org.smpp.WrongSessionStateException wsse) { wsse.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return successfull; }
     */
    
    /*
     * public int submitAndDeliverDataSM(String destAddr, String shortMessage) { int successfull = 0; dataSMrequest = new DataSM(); DataSMResp response; try { // Se asigna los parmetros obligatorios dataSMrequest.setServiceType(serviceType); dataSMrequest.setSourceAddr(sourceAddress); dataSMrequest.setDestAddr(destAddress); dataSMrequest.setEsmClass(esmClass); dataSMrequest.setRegisteredDelivery(registeredDelivery); dataSMrequest.setDataCoding(dataCoding); // send the request //System.out.println("Data request " + dataSMrequest.debugString()); if (asynchronous) { session.data(dataSMrequest); }
     * else { response = session.data(dataSMrequest); //System.out.println("Data response " + response.debugString()); messageId = response.getMessageId(); } } catch (org.smpp.pdu.ValueNotSetException vnse) { vnse.printStackTrace(); } catch (org.smpp.pdu.WrongLengthOfStringException wlose) { wlose.printStackTrace(); } catch (org.smpp.pdu.WrongDateFormatException wdfe) { wdfe.printStackTrace(); } catch (org.smpp.TimeoutException te) { te.printStackTrace(); } catch (org.smpp.pdu.PDUException pdue) { pdue.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch
     * (org.smpp.WrongSessionStateException wsse) { wsse.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return successfull; }
     */
    /**
     * Inicia el hilo responsable de invocar al mtodo receiveDeliverSM(). El mtodo receiveDeliverSM() es el encargado de recibir y procesar los mensajes del tipo DeliverSM del SMSC. El tipo de enlace debe ser como receiver/transceiver.
     *
     * @see #run()
     */
    public void receiveSMS() throws Exception {
        try {
            if (this.getToReceiver() == null) {
                this.setKeepReceiving(true);
                this.setToReceiver(new Thread(this));
                this.getToReceiver().setDaemon(true);
                this.getToReceiver().start();
                // this.getToReceiver().run();
            } else {
                if (this.getToReceiver().isAlive()) {
                    this.setKeepReceiving(true);
                } else {
                    this.setKeepReceiving(true);
                    this.getToReceiver().setDaemon(true);
                    this.getToReceiver().start();
                }
            }
        } catch (IllegalThreadStateException ie) {
            ie.printStackTrace();
            logger.error("", ie);
            throw ie;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("", e);
            throw e;
        }
    }
    
    /**
     * Mtodo cancelSM. Este mtodo es invocado para cancelar uno o ms mensajes cortos enviados previamente, <br>
     * y que todava no han sido entregados al destinatario. <br>
     *
     * @param messId
     *            Identificador del mensajes a ser cancelado. Este debe ser el message_id asignado <br>
     *            por el SMSC al mensaje original <br>
     * @param sourAddre
     *            Source Address (direccin de origen) del mensaje a ser cancelado.
     * @param destAddre
     * @param servType
     * @return boolean
     */
    public void cancelSM(String messId, String sourAddre, String destAddre, String servType) {
        boolean cancelado = false;
        
        CancelSM cancelSM = new CancelSM();
        CancelSMResp cancelResponse;
        try {
            cancelSM.setMessageId(messId);
            cancelSM.setSourceAddr(sourAddre);
            cancelSM.setDestAddr(destAddre);
            cancelSM.setServiceType(servType);
            
            if (asynchronous) {
                session.cancel(cancelSM);
            } else {
                cancelResponse = session.cancel(cancelSM);
                if (cancelResponse.isOk()) {
                    
                }
            }
        } catch (org.smpp.pdu.ValueNotSetException vnse) {
            vnse.printStackTrace();
        } catch (org.smpp.pdu.WrongLengthOfStringException wlose) {
            wlose.printStackTrace();
        } catch (org.smpp.pdu.WrongDateFormatException wdfe) {
            wdfe.printStackTrace();
        } catch (org.smpp.TimeoutException te) {
            te.printStackTrace();
        } catch (org.smpp.pdu.PDUException pdue) {
            pdue.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (org.smpp.WrongSessionStateException wsse) {
            wsse.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void querySM(String messId, String sourAddre, String destAddre, String servType) {
        QuerySM querySM = new QuerySM();
        QuerySMResp queryResponse;
        try {
            querySM.setMessageId(messId);
            querySM.setSourceAddr(sourAddre);
            
            if (asynchronous) {
                session.query(querySM);
            } else {
                queryResponse = session.query(querySM);
                if (queryResponse.isOk()) {
                    queryResponse.getMessageState();
                }
            }
        } catch (org.smpp.pdu.ValueNotSetException vnse) {
            vnse.printStackTrace();
        } catch (org.smpp.pdu.WrongLengthOfStringException wlose) {
            wlose.printStackTrace();
        } catch (org.smpp.pdu.WrongDateFormatException wdfe) {
            wdfe.printStackTrace();
        } catch (org.smpp.TimeoutException te) {
            te.printStackTrace();
        } catch (org.smpp.pdu.PDUException pdue) {
            pdue.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (org.smpp.WrongSessionStateException wsse) {
            wsse.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Detiene la recepcin de mensajes.
     *
     * @see #run()
     */
    public void stopReceiveSMS() {
        if (this.getToReceiver().isAlive()) {
            //this.toReceiver = null; --->Comentado 23/08/2006 para modificar
            // el stop del nodo
            this.setKeepReceiving(false);
            logger.info("keep receiving " + false);
        }
    }
    
    /**
     * Establece el status de la Autoreconexin
     *
     * @param status
     *            true (reconectar) / false (no reconectar).
     */
    public void setAutoReconnect(boolean status) {
        autoReconnect = status;
    }
    
    /**
     * Devuelve el status de la autoreconexin.
     *
     * @return true (reconectar) / false (no reconectar).
     */
    public boolean getAutoReconnect() {
        return autoReconnect;
    }
    
    // FIN DE LA IMPLEMENTACION DE LOS METODOS DE LA INTERFAZ SMPPConnector
    
    /**
     * Esta mtodo es el encargado de recibir los PDUs (mensajes) provenientes del SMSC. Este mtodo determina la forma del enlace (synchronous/asynchronous) y establece el tiempo de timeout para la recepcin de mensajes en 500 milisegundos. Es llamado por el Thread de "recepcin" cada un intervalo de tiempo. Siempre que un PDU es recibido, determina si es del tipo Request o Response y hace la llamada al mtodo guru.merlin.connectors.MessageHandler.SMSCRequest() guru.merlin.connectors.MessageHandler.SMSCResponse(), segn corresponda.
     */
    public void receiveDeliverSM() {
        
        Response response;
        try {
            PDU pdu = null;
            long longTimeout = 500;
            
            // Se recibe el mensaje
            if (asynchronous) {
                ServerPDUEvent pduReqEvent = pduListener.getRequestEvent(longTimeout);
                if (pduReqEvent != null) {
                    pdu = pduReqEvent.getPDU();
                }
                
                ServerPDUEvent pduRespEvent = pduListener.getResponseEvent(longTimeout);
                if (pduRespEvent != null) {
                    pdu = pduRespEvent.getPDU();
                }
            } else {
                pdu = session.receive(longTimeout);
            }
            
            if (pdu != null) {
                if (pdu.isRequest()) {
                    messageHandler.processSMSCRequest((Request) pdu);
                }
                if (pdu.isResponse()) {
                    messageHandler.processSMSCResponse((Response) pdu);
                }
            }
        } catch (org.smpp.pdu.ValueNotSetException vnse) {
            vnse.printStackTrace();
        } catch (org.smpp.pdu.WrongLengthOfStringException wlose) {
            wlose.printStackTrace();
        } catch (org.smpp.pdu.WrongDateFormatException wdfe) {
            wdfe.printStackTrace();
        } catch (org.smpp.TimeoutException te) {
            te.printStackTrace();
        } catch (org.smpp.pdu.PDUException pdue) {
            pdue.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /*
     * private ReceivedMessage buildMessage(org.smpp.pdu.DeliverSM deliverSM) { ReceivedMessage rMessage = null; DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.MEDIUM,Locale.FRANCE); DeliverSM deliverSMRequest = deliverSM; if (deliverSMRequest!=null) { rMessage = new ReceivedMessage(); Date time = new Date(); rMessage.setDelivery_Time(formatter.format(time)); String dadd = deliverSMRequest.getDestAddr().debugString(); rMessage.setDest_Address(dadd); String status = String.valueOf(deliverSMRequest.getCommandStatus()); rMessage.setDelivery_Status(status);
     * String msg = deliverSMRequest.getShortMessage(); rMessage.setShort_Message(msg); String sadd = deliverSMRequest.getSourceAddr().debugString(); rMessage.setSrc_Address(sadd); } return rMessage; }
     */
    
    /**
     * Esta mtodo es el encargado de enviar Enquire Links al SMSC. La idea de los Enquire Links es verificar el status de la comunicacin, adems de mantener viva la conexin con el SMSC.
     */
    public void toKeepAlive() throws Exception {//MOD SANTIAGO
        try {
            EnquireLink request = new EnquireLink();
            EnquireLinkResp response;
            if (asynchronous) {
                session.enquireLink(request);
            } else {
                response = session.enquireLink(request);
                messageHandler.processSMSCResponse(response);
            }
            this.setConnected(true);
        } catch (Exception ioe) {
            this.setConnected(false);                        
            logger.error("The Enquire Link failed "+this.nodeID ,ioe);
            throw ioe;
        } finally { 

        }
    }
    
    /**
     * Implementacin del mtodo run() de la interfaz Runnable. Se mantiene haciendo llamadas al mtodo receiveDeliverSM() mientras el valor de la propiedad keepReceiving sea igual a true o hasta que el mtodo stopReceiveSMS() sea llamado. Cada vez que el mtodo receiveDeliverSM() es llamado el hilo es puesto a dormir durante 30 milisegundos y el mtodo receiveDeliverSM() vuelve a ser invocado.
     */
    public void run() {
        if (nodeID != null) {
            Thread.currentThread().setName(nodeID);
        }
        
        try {
            long tiempo = 0;
            while (this.keepReceiving) {
                this.receiveDeliverSM();
                tiempo = 30;
                Thread.sleep(tiempo);
            }
            if (!this.keepReceiving) {
                logger.warn("The reception of messages has stopped.");
            }
        } catch (InterruptedException ie) {
            // ie.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * @param smsc
     *            identifica al operador (SMSC) ej. digitel, telcel, movilnet, etc
     */
    public void setSmscId(String smsc) {
        this.smscId = smsc;
    }
    
    /**
     * @return identificador del operador (SMSC) ej. digitel, telcel, movilnet, etc
     */
    public String getSmscId() {
        return smscId;
    }
    
    /**
     * @param pPath
     *            la ruta donde se encuentra el archivo de propiedades
     */
    public void setPropertiesPath(String pPath) {
        this.propertiesPath = pPath;
    }
    
    /**
     * @return la ruta donde se encuentra el archivo de propiedades
     */
    public String getPropertiesPath() {
        return propertiesPath;
    }
    
    /**
     * @param pFile
     *            El nombre del archivo de propiedades
     */
    public void setPropertiesFile(String pFile) {
        this.propertiesFile = pFile;
    }
    
    /**
     * @return El nombre del archivo de propiedades
     */
    public String getPropertiesFile() {
        return propertiesFile;
    }
    
    /**
     * Devuelve el status para el enlace con el SMSC.
     *
     * @return true (enlazado) / false (desenlazado).
     */
    public boolean isBound() {
        return bound;
    }
    
    /**
     * Asigna el status para el enlace con el SMSC.
     *
     * @param bound
     *            true (enlazado) / false (desenlazado).
     */
    private void setBound(boolean bound) {
        this.bound = bound;
    }
    
    /**
     * Devuelve el status para la conexin TCP/IP
     *
     * @return true (conectado) / false (desconectado).
     */
    public boolean isConnected() {
        return connected;
    }
    
    /**
     * Asigna el status para la conexin TCP/IP
     *
     * @param connected
     *            true (conectado) / false (desconectado).
     */
    private void setConnected(boolean connected) {
        this.connected = connected;
    }
    
    /**
     * Devuelve el valor del atributo asynchronous.
     *
     * @return true (asynchronous) / false (synchronous).
     */
    public boolean isAsynchronous() {
        return asynchronous;
    }
    
    /**
     * Asigna el valor del atributo asynchronous.
     *
     * @param asynchronous
     *            true (asynchronous) / false (synchronous).
     */
    private void setAsynchronous(boolean asynchronous) {
        this.asynchronous = asynchronous;
    }
    
    /**
     * El valor de este atributo es asignado por el SMSC a cada mensaje corto enviado.
     *
     * @return una cadena con el valor del atributo messageId.
     */
    public String getMessageId() {
        return messageId;
    }
    
    /**
     * Establece un nuevo valor para el atributo messageId. El valor de este atributo es asignado por el SMSC a cada mensaje corto enviado.
     *
     * @param messageId
     */
    private void setMessageId(String messageId) {
        this.messageId = messageId;
    }
    
    /**
     * Carga el archivo de propiedades necesario para el funcionamiento de las operaciones smpp.
     */
    public void loadProperties() {
        try {
            String path = getPropertiesPath();
            String file = getPropertiesFile();
            String prop = path + file;
            this.properties = new Properties();
            InputStream fis = new FileInputStream(prop);
            properties.load(fis);
            fis.close();
            
            nodeID = properties.getProperty("nodeID").trim();
            
            // CONNECTIONS
            ipAddress = properties.getProperty(getSmscId() + "_ip_address").trim();
            port = Integer.parseInt(properties.getProperty(getSmscId() + "_port").trim());
            
            // BIND
            systemId = properties.getProperty(getSmscId() + "_system_id").trim();
            password = properties.getProperty(getSmscId() + "_password").trim();
            systemType = properties.getProperty(getSmscId() + "_system_type").trim();
            addrTon = Byte.parseByte(properties.getProperty(getSmscId() + "_addr_ton").trim());
            addrNpi = Byte.parseByte(properties.getProperty(getSmscId() + "_addr_npi").trim());
            addrRange = properties.getProperty(getSmscId() + "_address_range", Data.DFLT_ADDR_RANGE);
            String intVersion = properties.getProperty(getSmscId() + "_interface_version");
            if (intVersion.equals("0x33")) {
                interfaceVersion = (byte) 0x33;
            } else if (intVersion.equals("0x50")) {
                interfaceVersion = (byte) 0x50;
            } else {
                interfaceVersion = (byte) 0x34;
            }
            
            String asynch = properties.getProperty(getSmscId() + "_asynchronous").trim();
            
            if (asynch.equalsIgnoreCase("true")) {
                setAsynchronous(true);
            } else if (asynch.equalsIgnoreCase("false")) {
                setAsynchronous(false);
            }
            
            String bindT = properties.getProperty(getSmscId() + "_bindType").trim();
            this.setBindType(bindT);
            
            // SUBMIT
            serviceType = properties.getProperty(getSmscId() + "_service_type");
            sourceAddrTon = Byte.parseByte(properties.getProperty(getSmscId() + "_source_addr_ton"));
            sourceAddrNpi = Byte.parseByte(properties.getProperty(getSmscId() + "_source_addr_npi"));
            // srcAddr = properties.getProperty(getSmscId() + "_source_addr");
            destAddrTon = Byte.parseByte(properties.getProperty(getSmscId() + "_dest_addr_ton"));
            destAddrNpi = Byte.parseByte(properties.getProperty(getSmscId() + "_dest_addr_npi"));
            esmClass = Byte.parseByte(properties.getProperty(getSmscId() + "_esm_class"));
            protocolId = Byte.parseByte(properties.getProperty(getSmscId() + "_protocol_id"));
            priorityFlag = Byte.parseByte(properties.getProperty(getSmscId() + "_priority_flag"));
            scheduleDeliveryTime = properties.getProperty(getSmscId() + "_schedule_delivery_time");
            validityPeriod = properties.getProperty(getSmscId() + "_validity_period");
            registeredDelivery = Byte.parseByte(properties.getProperty(getSmscId() + "_registered_delivery"));
            replaceIfPresentFlag = Byte.parseByte(properties.getProperty(getSmscId() + "_replace_if_present_flag"));
            dataCoding = Byte.parseByte(properties.getProperty(getSmscId() + "_data_coding"));
            smDefaultMsgId = Byte.parseByte(properties.getProperty(getSmscId() + "_sm_default_msg_id"));
            // smLength =
            // Integer.parseInt(properties.getProperty(getSmscId()+"_sm_length"));
            shortMessage = properties.getProperty(getSmscId() + "_short_message");
            
            // RECEIVE
            intTimeout = Integer.parseInt(properties.getProperty(getSmscId() + "_receive_timeout"));
            
            String enquireLinkT = properties.getProperty("enquire_link_time").trim();
            enquireLinkTime = Long.parseLong(enquireLinkT);
            
            driver = properties.getProperty("mercurio.db.driver");
            dbmsURL = properties.getProperty("mercurio.db.dbmsURL");
            username = properties.getProperty("mercurio.db.username");
            passworddb = properties.getProperty("mercurio.db.password");
        } catch (IOException ioe) {
            // System.out.println("Ha ocurrido una IOException durante la carga
            // del archivo de propiedades.");
            // System.out.println("loadProperties()");
            ioe.printStackTrace();
        } catch (NumberFormatException nfe) {
            // System.out.println("Ha ocurrido una NumberFormatException durante
            // la carga del archivo de propiedades.");
            // System.out.println("loadProperties()");
            nfe.printStackTrace();
        } catch (Exception exc) {
            // System.out.println("Ha ocurrido una NumberFormatException durante
            // la carga del archivo de propiedades.");
            // System.out.println("loadProperties()");
            exc.printStackTrace();
        }
    }
    
    /**
     * Getter for property toReceiver.
     *
     * @return Value of property toReceiver.
     */
    public java.lang.Thread getToReceiver() {
        return toReceiver;
    }
    
    /**
     * Setter for property toReceiver.
     *
     * @param toReceiver
     *            New value of property toReceiver.
     */
    public void setToReceiver(java.lang.Thread toReceiver) {
        this.toReceiver = toReceiver;
    }
    
    /**
     * Getter for property keepReceiving.
     *
     * @return Value of property keepReceiving.
     */
    public boolean isKeepReceiving() {
        return keepReceiving;
    }
    
    /**
     * Setter for property keepReceiving.
     *
     * @param keepReceiving
     *            New value of property keepReceiving.
     */
    public void setKeepReceiving(boolean keepReceiving) {
        this.keepReceiving = keepReceiving;
    }
    
    /**
     * Getter for property receivedMessageStore.
     *
     * @return Value of property receivedMessageStore.
     */
    public guru.mercurio.eps.sSMPP.DataHandler getDataHandler() {
        return dataHandler;
    }
    
    /**
     * Setter for property receivedMessageStore.
     *
     * @param receivedMessageStore
     *            New value of property receivedMessageStore.
     */
    public void setDataHandler(guru.mercurio.eps.sSMPP.DataHandler dataHandler) {
        this.dataHandler = dataHandler;
    }
    
    /**
     * Getter for property messageHandler.
     *
     * @return Value of property messageHandler.
     */
    public guru.mercurio.eps.sSMPP.ReceivedMessageHandler getMessageHandler() {
        return messageHandler;
    }
    
    /**
     * Setter for property messageHandler.
     *
     * @param messageHandler
     *            New value of property messageHandler.
     */
    public void setMessageHandler(guru.mercurio.eps.sSMPP.ReceivedMessageHandler messageHandler) {
        this.messageHandler = messageHandler;
    }
    
    /**
     * Returns the bindType.
     *
     * @return String
     */
    public String getBindType() {
        return bindType;
    }
    
    /**
     * Sets the bindType.
     *
     * @param bindType
     *            The bindType to set
     */
    public void setBindType(String bindType) {
        this.bindType = bindType;
    }
    
    public Session getSession() {
        return this.session;
    }
    
    /*
     * AGREGADO TEMPORALMENTE POR SANTIAGO. MIENTRAS LA ACTUALIZACION DE LOS ESTADOS DE ERROR EN LOS MDR SE HA MANEJADO POR EL BEAN
     */
    
    public static String driver;
    
    public static String dbmsURL;
    
    public static String username;
    
    public static String passworddb;
    
    public long getEnquireLinkTime() {
        return enquireLinkTime;
    }
    
    public void setEnquireLinkTime(long enquireLinkTime) {
        this.enquireLinkTime = enquireLinkTime;
    }
    
} // FIN DE LA CLASE SMPPOperator
